package cmd

import (
	"bytes"
	"fmt"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"io/ioutil"
	"net"
	"os"
	"sync"
	"time"
)

func tcp(cmd *cobra.Command, args []string) {
	var wg sync.WaitGroup
	fs := viper.GetStringSlice("files")
	msgs := viper.GetStringSlice("messages")
	for i, msg := range msgs {
		wg.Add(1)
		go func(fn, msg string) {
			defer func() {
				wg.Done()
				if err, ok := recover().(error); ok && err != nil {
					fmt.Println(err)
				}
			}()
			call(fn, msg)
		}(fs[i], msg)
	}

	wg.Wait()
}

func connect() net.Conn {
	conn, err := net.Dial("tcp", viper.GetString("addr"))
	if err != nil {
		panic(fmt.Errorf("Tcp connect fail, %s \n", err))
	}

	conn.SetDeadline(time.Now().Add(viper.GetDuration("timeout")))
	return conn
}

func call(fn, msg string) {
	conn := connect()
	defer conn.Close()

	sb := []byte(msg)
	if n, err := conn.Write(sb); err != nil || n != len(sb) {
		panic(fmt.Errorf("[%d/%d]Write fail: %s : %s \n", n, len(sb), err, msg))
		return
	}

	var buf bytes.Buffer
	_,err := buf.ReadFrom(conn)
	if err != nil {
		panic(fmt.Errorf("Read fail: %s : %s \n", err, buf.String()))
	}

	var log bytes.Buffer
	log.WriteString(fmt.Sprintf("[%s] Send: [%s] \n", fn, msg))
	log.WriteString("\n-----------------------------------------------\n\n")
	log.WriteString(fmt.Sprintf("[%s] Recieve: [%s] \n", fn, buf.String()))
	ioutil.WriteFile(fn+".log", log.Bytes(), os.FileMode(0666))
}
